
;(function(win,doc){

    if(!win.console){
        win.console = {
            log : function(){},
            error : function(){},
            info : function(){},
            success : function(){},
            warning : function(){},
        }
    }

    //_addEvent 添加事件,私有
    function _addEvent(o,e,f,useCapture){
        useCapture = useCapture || false;
        if(win.attachEvent){
            o.attachEvent('on'+e,function(){
                f.call(this,o);
            });
        }else{
            o.addEventListener(e,f,useCapture);
        }
    }

     //_removeEvent 移除事件,私有
    function _removeEvent(o,e,f,useCapture){
        useCapture = useCapture || false;
        if(win.detachEvent){
            o.detachEvent('on'+e,function(){
                f.call(this,o);
            });
        }else{
            o.removeEventListener(e,f,useCapture);
        }
    }


    // 批量添加事件 _batchAddEvents ,私有
    function _batchAddEvents(elements,e,f,useCapture){
        for(i=0;i<elements.length;i++){
            _addEvent(elements[i],e,f,useCapture);
        }
    }


    //定义Pml对象
    function Pml(args){//参数是变体变量
        this.elements=[];//选择器选择的元素扔到这个数组中

        switch(typeof args){
            //如果参数是函数
            case 'function':
                _addEvent(win,'load',args);
                break;
            //如果参数是字符串
            case 'string':
                var eles = doc.querySelectorAll(args);

                this.elements=[].slice.call(eles);

                break;
            //如果参数是对象。
            case 'object':
                if(!args){
                     break;
                }else if(this.isArray(args)){
                    this.elements = args;
                }else{
                    this.elements.push(args);
                }
                break;

        }

    }

    //定义简写
    function _$(args){
        return new Pml(args);
    }

    Pml.prototype = {
        get : function(i){
            //获取其中一个元素
            if(i && this.elements[i]){
                return this.elements[i];
            }else{
                return this.elements && this.elements.length > 0 ? this.elements[0] : [];
            }
        },
        style : function(o,s){
            //设置或获取样式
            //o 是属性 例如：width
            //s 是值 例如 ：200px
            if(s){
                //如果第二个参数（值）存在说明是添加样式
                for(i=0;i<this.elements.length;i++){
                    this.elements[i].style[o]=s;
                }
                return this;
            }

            //获取样式
            if(o.currentStyle){
                //兼容ie9及以下
                return o.currentStyle[s];
            }else{
                var el = this.elements[0];
                // 注意：此处为了解决当 style 值为 auto 时，返回 auto 的问题
                var w = el.ownerDocument.defaultView;
                // false 的意思是不返回伪类元素
                return w.getComputedStyle(el,false)[o];
            }
        },
        height : function(){
            return this.elements[0].offsetHeight;
        },
        width : function(){
            return this.elements[0].offsetWidth;
        },
        append : function(txhtml){
            //匹配元素的后面 （选中元素内部）
            var el = this.elements[0];
            el.insertAdjacentHTML('beforeend',txhtml);
            return this;
        },
        prepend : function(txhtml){
            //匹配元素的前面 （选中元素内部）
            var el = this.elements[0];
            el.insertAdjacentHTML('afterbegin',txhtml);
            return this;
        },
        after : function(txhtml){
             //匹配元素的后面 （选中元素外）
            var el = this.elements[0];
            el.insertAdjacentHTML('afterend',txhtml);
            return this;
        },
        before : function(txhtml){
            ////匹配元素的前面 （选中元素外）
            var el = this.elements[0];
            el.insertAdjacentHTML('beforebegin',txhtml);
            return this;
        },
        off : function(e,f){
            //off 解绑事件
            //e :需要解绑的事件 例如：click
            //f :解绑之后的回调函数

            for(i=0;i<this.elements.length;i++){

                _removeEvent(this.elements[i],e,f);
            }
            return this;
        },

        on : function(e,el,f){
            //on的方式绑定事件
            //e事件
            //el 子元素
            //f触发事件
            //两个参数是冒泡事件，三个参数是捕获事件

            if(arguments.length === 3){
                //_addEvent
                for(var i =0;i < this.elements.length;i++){

                    _addEvent(this.elements[i],e,function(e){
                        var e = e || win.event,
                            target = e.srcElement || e.target;

                        //判断是否是目标元素
                        var isTatget = _$(this).find(el).inArray(target);
                        if(isTatget > -1){
                             f.call(target,e);
                         }

                    });
                }

            }else if(arguments.length === 2 && typeof el === 'function'){
                f = el;
                _batchAddEvents(this.elements,e,f);
            }else{
                console.error('参数错误');
            }

            return this;

        },
        click : function(f){

            //click事件

            _batchAddEvents(this.elements,'click',f);

            return this;
        },
        focus : function(f){
            //focus事件
            _batchAddEvents(this.elements,'focus',f);
            return this;
        },
        blur : function(f){
            //blur事件
            _batchAddEvents(this.elements,'blur',f);
            return this;
        },
        change : function(f){
            //change事件
             _batchAddEvents(this.elements,'change',f);
            return this;
        },
        show : function(){
            //对选择器函数绑定show/hide事件
            for(var i=0;i<this.elements.length;i++){
                this.elements[i].style.display='block';
            }
            return this;
        },
        hide : function(){
            for(var i=0;i<this.elements.length;i++){
                this.elements[i].style.display='none';
            }
            return this;
        },
        hover : function(fnover,fnout){
            _batchAddEvents(this.elements,'mouseenter',fnover);
            _batchAddEvents(this.elements,'mouseleave',fnout);

            return this;
        },
        addClass : function(className){
            //对于返回器数组的内容
            for(var i=0;i<this.elements.length;i++){

                this.elements[i].classList.add(className);
            }
            return this;
        },
        removeClass : function(className){
            //对于返回器数组的内容
            for(var i=0;i<this.elements.length;i++){
                this.elements[i].classList.remove(className);
            }
            return this;
        },
        hasClass : function(className){
            var el = this.elements[0];
            return el.classList.contains(className);
        },
        css : function(attr,value){
            //css方法,添加或获取样式
            //如果是两个string参数，则添加样式
            //如果只有一个参数：
            //               1、string : 获取样式 例如：color
            //               2、对象设置样式 例如 ： {color : 'red'}
            if(arguments.length === 2){
                this.style(attr,value);
            }else{
                if(typeof attr === 'string'){
                    return  this.style(attr);
                }else {
                    for(var o in attr){
                         this.style(o,attr[o]);
                    }
                }
            }

            return this;
        },
        attr : function(attr,value){
            if(arguments.length==2){//设置属性
                var i=0;

                for(i=0;i<this.elements.length;i++){
                    this.elements[i][attr]=value;
                }
            }else{//获取属性
                return this.elements[0][attr];
            }
        },
        val : function(v){
            //获取或这是文本的值
            //v 若为空 获取值
            var el = this.elements[0];
            if(v){
                el.value = v;
            }else{
                return el.value;
            }
        },
        index : function(radio){
            //获取单选按钮所在的位置
            var el = this.elements[0];

            return [].indexOf.call(doc.querySelectorAll(radio), el);
        },
        siblings : function(){
            //获取所有的兄弟元素
            var el = this.elements[0];
            var _el = [].filter.call(el.parentNode.children, function(child) {
              return child !== el;
            });

            return _$(_el);
        },
        prev : function(){
             //获取当前元素的前一个元素
            var el = this.elements[0];

            return _$(el.previousElementSibling);
        },
        next : function(){
             //获取当前元素的前一个元素
            var el = this.elements[0];
            return _$(el.nextElementSibling);
        },
        remove : function(){
            //移除元素
            var el = this.elements[0];
            el.parentNode.removeChild(el);
            return this;
        },
        text : function(_text){
            //获取/设置文本
            var el = this.elements[0];
            if(typeof _text !== 'undefined'){
                el.textContent = _text;
            }else
                return el.textContent;
        },
        html : function(_html){
            //获取/设置html
            var el = this.elements[0];

            if(typeof _html !== 'undefined'){
                el.innerHTML = _html;
            }else
                return el.innerHTML;
        },
        trigger : function(e,o){
            //自动触发事件
            var el = this.elements[0];
           if (win.CustomEvent) {
              var event = new CustomEvent(e, o);
            } else {
              var event = doc.createEvent('CustomEvent');
              event.initCustomEvent(e, true, true, o);
            }

            el.dispatchEvent(event);

            return this;
        },
        eq : function(n){
            //eq选择器
            return _$(this.elements[n]);
        },
        find : function(selector){
            //find选择器
            var i=0;
            var _elements=[];//存放临时数据

            for(i=0;i<this.elements.length;i++){
               _elements = _elements.concat([].slice.call(this.elements[i].querySelectorAll(selector)));
            }
            return  _$(_elements);//保持可链。
        },
        closest : function(selector){

            //parent选择器

            var el = this.elements[0].parentNode;

            var matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;

            while (el) {
                if (matchesSelector.call(el, selector)) {
                    // return el;
                    break;
                } else {
                    el = el.parentElement;
                }
            }
            return _$(el);

        },
        isArray : function(arr){
            //判断是否是数组

            if(!arr){
                return Array.isArray(this.elements);
            }

            return Array.isArray(arr);
        },
        inArray : function(val,arr){

            //判断是否在数组中，在返回所在的位置下标 不在返回-1
            if(arr && this.isArray(arr)){
                return arr.indexOf(val);
            }

            return this.elements.indexOf(val);
        },
        each : function(f){
            var els =  this.elements;
            for(var i =0; i < els.length ;i++){
                if(f.call(this,i,els[i]) === false){
                    break;
                }
            }
        },
        isEmpty : function(o){
            //对象/数组是否为空
            if(!o){
                o = this.elements;
            }
            if(this.isArray(o)){
                return o.length === 0;
            }else{
                return this.isEmptyObject(o);
            }
        },
        isEmptyObject : function(o){
            //判断对象是否为空
            if(!o){
                o = this.elements[0] || o;
            }
            for(var i in o){
                return !1;
            }
            return !0;
        },

        data : function(k,v){
             //data

            if(!v){
                return this.elements[0].getAttribute('data-'+k);
            }else{
                for(var i =0;i < this.elements.length;i++){
                    this.elements[i].setAttribute('data-'+k,v);
                }

            }

        },

        size : function(){
            return this.elements.length || 0;
        },

        length : function(){
            return this.elements.length || 0;
        },

    }


    _$.isArray = function(arr){
        return _$(arr).isArray();
    }

    //判断是否在数组中，在返回所在的位置下标 不在返回-1
    _$.inArray = function(val,arr){
        if(!val || !arr || arr.length === 0) return -1;
        return arr.indexOf(val);
    }
    _$.isEmpty = function(o){
        return $(o).isEmpty();
    }

    _$.isEmptyObject = function(o){
        return $(o).isEmptyObject();
    }

    _$.each = function(data,f){
        _$(data).each(f);
    }

    _$.stopPropagation = function(e){
        //组织事件冒泡
         win.event ? win.event.cancelBubble = true : e.stopPropagation();
    }
    _$.preventDefault = function(e){
        //组织默认行为
        win.event? win.event.returnValue = false : e.preventDefault();
    }

    //继承对象
    _$.extend = function(o1,o2,o3){
        return Object.assign(o1,o2,o3);
    }

    _$.xy = function(event){
        var e =event || win.event;
        var scrollX = doc.documentElement.scrollLeft || doc.body.scrollLeft,
            scrollY = doc.documentElement.scrollTop || doc.body.scrollTop;
        var x = e.pageX || e.clientX + scrollX,
            y = e.pageY || e.clientY + scrollY;
        return {x : x , y : y}
    }

    _$.target = function(event){
        var event = event || win.event,
        target = event.srcElement || event.target;
        return target;
    }

    _$.drag = function(box,handle,range){
       function Drag(){

            self = this;

            this.initialize = function(){
                this.drag = _$(box);
                this.handle = _$(handle);
                this._x = this._y = 0;

                this.handle.css('cursor','move');
                this.drag.css('position','absolute');

                this.handle.on('mousedown',this.startDrag);
            }

            this.startDrag=function(event){
                var event = event || window.event;

                self._x = event.clientX - self.drag.get().offsetLeft;
                self._y = event.clientY - self.drag.get().offsetTop;

                event.preventDefault();

                _$(range).on('mousemove',self.moveDrag);
                _$(range).on('mouseup',self.stopDrag);
            }

            this.moveDrag = function(event){
                var event = event || window.event;

                var iTop = event.clientY - self._y;
                var iLeft = event.clientX - self._x;

                self.drag.css({'top': iTop+'px','left':iLeft + 'px'});

                event.preventDefault();
            },
            this.stopDrag = function(event){

                _$(range).off('mousemove',self.moveDrag);
                _$(range).off('mouseup',self.stopDrag);
            }

            this.initialize(arguments);
       }


       new Drag(box,handle,range);

    }



    if(!win.$){
        win.pml = win.$ = _$;
    }else{
        win.pml = _$;
     }

})(window,document);

;(function(win,doc,$){

    $.PmlArea = function(options){

        var self = this;

        var setting = {
            data : [],
            split : ',',
            title : ['省份','城市','区/县'],
            autoClose : true,                   //选择最后一级后是否自动关闭 true 自动关闭
            textType : 1,                       //选择后显示那种值 1:name 2:val 3:code 默认name
            valueType : 1,                      //  选择后取那种值 1:value 2:code 3:name 默认value
            defaultVal:[],                      //默认值code/value
            timeout : 0,                        //自动关闭延迟的时间
            end : null,                         //点击最后的回掉函数

        }

        var config = {
            visible : false,    //是否可见
            defaults : '',      //默认值
            pindex : -1,        //省份下标
            cindex : -1,        //城市下标
            cyindex : -1,       //区/县下标
            target : null,      //目标元素
            value : '',         //最后的值
            text : '',
            isEnd : false,      //是否已经结束

        }

        var ops = $.extend({},setting,options);
        ops.el = '<div class="pml-area" id="pml-area"><span class="area-close"></span><ul class="area-nav area-nav-tabs area-title-tabs"><li class="active"><a href="#area-province" id="area-province-tab" data-tab="#area-province">{title.province}</a></li><li><a href="#area-city" id="area-city-tab" data-tab="#area-city">{title.city}</a></li><li><a href="#area-county" id="area-county-tab" data-tab="#area-county">{title.county}</a></li></ul><div class="area-tab-content"><div class="area-tab-pane active" data-tab="province" data-index="-1" id="area-province" data-next-tab = "#area-city"><ul></ul></div><div class="area-tab-pane" id="area-city" data-index="-1" data-tab="city" data-next-tab = "#area-county"><ul></ul></div><div class="area-tab-pane" data-tab="county" data-index="-1" id="area-county"><ul></ul></div></div></div>';
        ops.sub_el = '<li data-index="{index}" data-code="{code}" data-value="{value}"><span>{name}</span></li>';


        //初始化弹出层
        function _init(){
            //
            var _el = ops.el.replace('{title.province}',ops.title[0]).replace('{title.city}',ops.title[1]).replace('{title.county}',ops.title[2]);
            $('body').append(_el);

            //直接初始化省
            var txhtml = _txhtml(ops.data);

            $('#area-province ul').html(txhtml);
        }

        //获取通用的HTML
        function _txhtml(data){
            if(data && data.length > 0){
                var tpl = ops.sub_el,
                    txhtml = [];
                $.each(data,function(i,item){
                    txhtml.push(tpl.replace('{index}',i).replace('{code}',item.code).replace('{value}',item.value).replace('{name}',item.name));
                });

                return txhtml.join('');
            }
            return '';
        }

        //设置默认值
        //o tab元素 v 值
        function _setDefaultValue(o,v){
            o.find('ul>li.active').removeClass('active');
            var defel = o.find('ul>li[data-code="'+v+'"]') || o.find('ul>li[data-value="'+v+'"]');

            if(defel.length() > 0){
                defel.addClass('active');

                defel.closest('.area-tab-pane').data('index',defel.data('index'));

                var nextTab = defel.closest('.area-tab-pane').data('next-tab');
                if(nextTab){
                    if(ops.data[defel.data('index')].subs.length > 0)
                        self.goto(nextTab);
                }else{
                    config.cyindex = Number(defel.data('index'));
                }
            }
        }

        function _handlerDefaultVal(){
            var defaultVal = ops.defaultVal;
            if(defaultVal || ops.defaultVal){
                defaultVal = (defaultVal || ops.defaultVal) || [];
                if(typeof defaultVal === "string"){
                    defaultVal = defaultVal.split(ops.split);
                }

                if(defaultVal.length > 0){
                    return defaultVal;
                }
            }
            return [];
        }



        //重置头部信息
        function _resetTitle(){
            //重置头部信息
            $('.area-title-tabs li').removeClass('active');
            $('.area-title-tabs li').eq(0).addClass('active');

            //同时Tab内容,也要重置
            $('.area-tab-pane').removeClass('active');
            $('.area-tab-pane').eq(0).addClass('active');
            $('.area-tab-pane').data('index',-1);
            $('.area-tab-pane ul>li').removeClass('active');
            config.pindex = -1;
            config.cindex = -1;
            config.cyindex = -1;

            $('#area-city ul').html('');
            $('#area-county ul').html('');

            ops.defaultVal = '';
        }

        function _resetProvince(){
            var defaultVal = _handlerDefaultVal();

            if(defaultVal && defaultVal.length > 0){

                _setDefaultValue($('#area-province'),defaultVal[0]);

                _resetCity();

            }
        }

        function _resetCity(f){
            config.cindex = -1;
            $('#area-city').data('index',-1);
            $('#area-city ul').html('');

            var pindex = Number($('#area-province').data('index'));
            if(pindex <= -1) return ;

            config.pindex = pindex;

            var subs = ops.data[pindex].subs,
                isEnd = true;
            if(subs && subs.length > 0){

                isEnd = false;

                var txhtml = _txhtml(subs);

                $('#area-city ul').html(txhtml);


                var defaultVal = _handlerDefaultVal();
                if(defaultVal && defaultVal.length > 0){

                     _setDefaultValue($('#area-city'),defaultVal[1]);

                     _resetCounty(f);

                }
            }

            if(f) f.call(this,isEnd);
        }

        function _resetCounty(f){
            config.cyindex = -1;
            $('#area-county').data('index',-1);
            $('#area-county ul').html('');

            var cindex = Number($('#area-city').data('index'));
            if(cindex <= -1) return ;
            config.cindex = cindex;
            var subs = ops.data[config.pindex].subs[cindex].subs,
                isEnd = true;
            if(subs && subs.length > 0){

                isEnd = false;

                var txhtml = _txhtml(subs);

                $('#area-county ul').html(txhtml);

                var defaultVal = _handlerDefaultVal();
                if(defaultVal && defaultVal.length > 0){
                    _setDefaultValue($('#area-county'),defaultVal[2]);
                }
            }

            if(f) f.call(this,isEnd);

        }




        function _getProvince(){
            var pindex = config.pindex;
            if(pindex > -1){
                var p = ops.data[pindex];
                return {name : p.name,code : p.code,value : p.value}
            }
            return false;
        }

        function _getCity(){
            var pindex = config.pindex,
                cindex = config.cindex;
            if(pindex < 0){
                return false;
            }else if(cindex < 0){
                return false;
            }else{
                var citys = ops.data[pindex].subs;
                if(citys && citys.length > 0){
                    var city = citys[cindex] || {};
                    return {name : city.name,code : city.code,value : city.value}
                }
                return false;
            }
        }

        function _getCounty(){
            var pindex = config.pindex,
                cindex = config.cindex,
                cyindex = config.cyindex;

            if(pindex < 0 || cindex < 0 || cyindex < 0){
                return false;
            }else{
                var county = ops.data[pindex].subs?ops.data[pindex].subs[cindex].subs[cyindex]:{};
                return {name : county.name ,code : county.code,value : county.value}
            }
        }



        function _handlerData(){
            var target = config.target,
                split = ops.split,
                textType = Number(ops.textType),
                valueType = Number(ops.valueType),
                text = [], value = [], code = [],

                province = _getProvince(),
                city = _getCity(),
                county = _getCounty();

            if(province){
                text.push(province.name);
                value.push(province.value);
                code.push(province.code);

                if(city){
                    text.push(city.name);
                    value.push(city.value);
                    code.push(city.code);

                    if(county){
                        text.push(county.name);
                        value.push(county.value);
                        code.push(county.code);
                    }
                }
            }

            var _text = '',_value = '';

            if(textType === 1){
                _text = text.join(split);
            }else if(textType === 2){
                _text = value.join(split);
            }else{
                _text = code.join(split);
            }

            if(valueType === 1){
                _value = value.join(split);
            }else if(valueType === 2){
                _value = code.join(split);
            }else{
                _value = text.join(split);
            }

            var nodeName = target.nodeName.toUpperCase();
            if(nodeName === 'INPUT' || nodeName === 'SELECT' || nodeName === 'TEXTAREA'){
                $(target).val(_text);
            }else{
                $(target).text(_text);
            }

            $(target).data('value',_value);

            config.text = _text;
            config.value = _value;


            //回掉函数
            if(ops.end){
                ops.end.call(this,config.value,config.text);
            }


        }

        function _hidePmlArea(){
            $('#pml-area').hide();
            config.visible = false;

            _handlerData();
        }

        function _showPmlArea(){
            $('#pml-area').show();
            config.visible = true;
            _resetProvince(ops.defaultVal);

        }
        function _event(){
            //关闭的点击事件
            $('.area-close').click(function(e){
                 $.stopPropagation(e);//阻止冒泡
                 _hidePmlArea();
            });


            //tab 标题点击事件
            $('.area-title-tabs > li > a').click(function(e){
                $.stopPropagation(e);//阻止冒泡

                var curLi = $(this).closest('li');
                if(curLi.hasClass('active')){
                    return ;
                }
                curLi.siblings().removeClass('active');
                curLi.addClass('active');
                var tab = $(this).data('tab');
                self.goto(tab);
            });

            //省/市/区的点击事件
            $('.area-tab-pane').on('click','li>span',function(e){
                 $.stopPropagation(e);//阻止冒泡
                 var curLi = $(this).closest('li');

                 curLi.siblings().removeClass('active');
                 curLi.addClass('active');
                 var nextTab = $(this).closest('.area-tab-pane').data('next-tab');
                 $(this).closest('.area-tab-pane').data('index',curLi.data('index'));

                 var curTab = $(this).closest('.area-tab-pane').data('tab');

                 if(curTab === 'province'){
                    _resetCity(function(isEnd){
                        if(isEnd){
                            _end();
                        }else{
                            self.goto(nextTab);
                        }
                    });
                    //_refreshCity();
                 }else if(curTab === 'city'){
                    _resetCounty(function(isEnd){
                        if(isEnd){
                            _end();
                        }else{
                            self.goto(nextTab);
                        }

                    });
                 }else{
                    config.cyindex = Number(curLi.data('index'));

                    _end();
                 }


                 function _end(){


                    if(ops.autoClose){
                        var timeoutIndex = setTimeout(function(){
                            _hidePmlArea();

                            clearTimeout(timeoutIndex);

                        }, ops.timeout);
                    }
                 }

            });


        }



        this.goto = function(tab){
            var li = $('[data-tab="'+tab+'"]').closest('li');
            if(!li.hasClass('active')){
                li.siblings().removeClass('active');
                li.addClass('active');
            }
            $(tab).siblings().removeClass('active');
            $(tab).addClass('active');
        }
        this.show = function(e,init){
            if(config.visible){
                return ;
            }

            _resetTitle();

            config.target = $.target(e);

            if(arguments.length === 3){
                ops.defaultVal = arguments[1];
                ops.end = arguments[2];
            }else if(arguments.length === 2){
                ops.defaultVal = arguments[1];
            }else if(arguments.length === 1){
                ops.defaultVal = $(config.target).data('value') || [];
            }

            //显示弹出层
            var pmlArea = $('#pml-area');

            var xy = $.xy(e);
            pmlArea.css({left : xy.x + 'px',top : (xy.y + $(e.target).height())+'px'});
            _showPmlArea();

            $.drag('#pml-area','.area-title-tabs',document);

        }

        _init();
        _event();

    }
})(window,document,pml);

